package org.fnzn.util;


import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.fnzn.exception.MyException;
/**
 * 反射工具类
 * @author zhaolulu
 *
 */
public class ParamsReflectUtils {
	/**
     * 获取当前对象对应字段的属性值（对象）
     * 声明，需要注意在NoSuchFieldException异常捕捉中捕获自己需要的属性字段进行拦截，告诉当查询这些属性名的时候，指定是查找的哪些对象，如果不告诉它，它是不知道的
     * @param obj    当前对象
     * @param field  需要获取的属性名，可以是当前对象中的属性名， 也可以是当前对象中的对象的属性名
     * @return    Object  当前对象指定属性值
     */
    public static String getFieldValue(Object obj, String field) /*throws Exception*/{
        Class<?> claz = obj.getClass();
        Field f = null;
        Object fieldValue = null;
        try {
            f = claz.getDeclaredField(field);
            f.setAccessible(true);
            fieldValue = f.get(obj);
            /*if(obj instanceof FrontInfoFinRpt&&f.getGenericType().getTypeName().equals("java.math.BigDecimal")){
            	if(fieldValue==null||Integer.parseInt(fieldValue.toString())==0){
            		return null;
            	}
            }else{
	            if(fieldValue==null) {
	            	return null;
	            }
            }*/
            if(fieldValue==null) {
            	return null;
            }
            return fieldValue.toString();
        } catch (Exception e) {
            e.printStackTrace();
            //throw new Exception("获取属性值失败");
            return null;
        }        
    }
    /**
     * 根据属性名设置对象属性值
     * @param obj  对象
     * @param field 属性名
     * @param value 属性值
     * @return
     */
    public static void setFieldValue(Object obj, String field,Object value){
        Class<?> claz = obj.getClass();
        Field f = null;
        try {
            f = claz.getDeclaredField(field);
            f.setAccessible(true);
            f.set(obj, value);
        } catch (Exception e) {
            e.printStackTrace();
            throw new MyException("设置属性值失败");
        }        
    }
    /**
     * 判断对象中是否存在指定的属性
     * @param obj
     * @param field
     * @return
     */
    public static boolean isExistFile(Object obj, String field){
    	Class<?> claz = obj.getClass();
        try {
        	claz.getDeclaredField(field);
            return true;
        } catch (Exception e) {
            return false;
        }        
    }
    
    public static Object getFieldValueByName(String fieldName, Object o) {  
        try {    
            String firstLetter = fieldName.substring(0, 1).toUpperCase();    
            String getter = "get" + firstLetter + fieldName.substring(1);    
            Method method = o.getClass().getMethod(getter, new Class[] {});    
            Object value = method.invoke(o, new Object[] {});    
            return value;    
        } catch (Exception e) {    
        	e.printStackTrace(); 
            return null;    
        }    
    } 
   /** 
     * 获取属性名(id)，属性值(value)的map组成的list 
     * */  
   public static List<Map<String,Object>> getFiledsInfo(Object o){
	   List<Map<String,Object>> list = new ArrayList<Map<String,Object>>();  
	   list=getFiledsInfos(o,list);   
	   return list;
    }
    /** 
     * 获取属性名(id)，属性值(value)的map组成的list  若属性是对象，递归组装
     * */  
    private static List<Map<String,Object>> getFiledsInfos(Object o,List<Map<String,Object>> list){ 
    	 Class<?> claz = o.getClass();
    	 Field[] fields=claz.getDeclaredFields();   
             Map<String,Object> infoMap=null; 
             Field f=null;        
	     for(int i=0;i<fields.length;i++){  	         	          	        
			 try {
				f = claz.getDeclaredField(fields[i].getName());
				f.setAccessible(true);
				if(f.get(o)!=null) {
					Type type=f.getGenericType();
					if(type.getTypeName().startsWith("org.fnzn.bean")){
						getFiledsInfos(f.get(o),list);
					}else{
						infoMap = new HashMap<String,Object>();  
						infoMap.put("id", fields[i].getName());
						infoMap.put("value",f.get(o));
						list.add(infoMap); 
					}					
				}				
			} catch (Exception e) {
					e.printStackTrace();
			} 	        
	      }  
	     return list;  
    }  
}
